/******************************************************************************************************
Copyright (C) 2017 Mestrelab Research S.L. All rights reserved.

This file is part of the MNova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/

/*globals BaseConverter, NMRSpectrum, Molecule, NMRAssignments, File, TextStream, Str, Env, Application*/
/*jslint plusplus: true, indent: 4*/

/** Default constructor of the converter
 * Defines the file filter
*/
function AssignmentsConverter() {
	"use strict";
	BaseConverter.call(this);
	this.exportFileFilter = "Assignments (*.txt)"; //!< It will override any other script converter with the same exportFileFilter
}
AssignmentsConverter.prototype = new BaseConverter();

/** Can export Molecules and Spectra with assignments
 */
AssignmentsConverter.prototype.wantsExport = function (aPageItems) {
	"use strict";
	var i, nmrSpc, linkedMols, mol, assignments;

	for (i = 0; i < aPageItems.length; i++) {
		if (aPageItems[i].name === "NMR Spectrum") {
			nmrSpc = new NMRSpectrum(aPageItems[i]);
			if (nmrSpc.isValid()) {
				linkedMols = nmrSpc.getNMRAssignedMolecules();
				if (linkedMols.length) {
					mol = new Molecule(linkedMols[0]);
					if (mol.isValid()) {
						assignments = new NMRAssignments(mol);
						return assignments.hasAssignments();
					}
				}
			}
		} else if (aPageItems[i].name === "Molecule") {
			mol = new Molecule(aPageItems[i]);
			assignments = new NMRAssignments(mol);
			return assignments.hasAssignments();
		}
	}
	return false;
};


/** Writes the file
 */
AssignmentsConverter.prototype.exportItems = function (aPageItems, aFilename) {
	"use strict";
	var strm, mol, i, spec, linkedMols, assignments, corrArray, c, ai, atom, atomLabel,
		shift, corrAtoms, corrString, corr, indx, noEqs, noEqHs, hIndex, h, protonLabel,
		decimals = 2,
		file = new File(aFilename);

	if (file.open(File.WriteOnly)) {
		strm = new TextStream(file);
		for (i = 0; i < aPageItems.length; i++) {
			if (aPageItems[i].name === "Molecule") {
				mol = new Molecule(aPageItems[i]);
				break;
			} else {
				spec = new NMRSpectrum(aPageItems[i]);
				if (spec.isValid()) {
					linkedMols = spec.getNMRAssignedMolecules();
					if (linkedMols.length) {
						mol = new Molecule(linkedMols[0]);
						break;
					}
				}
			}
		}

		if (mol !== undefined) {
			assignments = new NMRAssignments(mol);
			if (assignments.hasAssignments()) {
				//headers
				strm.write("Atom", "\t", "Chemical Shift", "\t");
				corrArray = assignments.correlations();
				for (c = 0; c < corrArray.length; c++) {
					strm.write(corrArray[c], "\t");
				}
				strm.write("\n");

				//values
				for (ai = 1; ai <= mol.atomCount; ai++) {
					atom = mol.atom(ai);
					atomLabel = atom.number;
					strm.write(atomLabel, "  ", atom.elementSymbol, "\t");

					//heavy atoms
					shift = assignments.chemShift(ai);
					if (shift !== undefined) {
						shift = shift.shift.toFixed(decimals);
						strm.write(shift, "\t");
					} else {
						strm.write("\t");
					}
					for (c = 0; c < corrArray.length; c++) {
						corrAtoms = assignments.correlatedAtoms(ai, 0, corrArray[c]);
						corrString = "";
						for (corr = 0; corr < corrAtoms.length; corr++) {
							if (corr > 0) {
								corrString  += ", ";
							}
							atomLabel = mol.atom(corrAtoms[corr].atom).number;
							for (indx = 0; indx < corrAtoms[corr].indexes.length; indx++) {
								if (indx > 0) {
									corrString  += ", ";
								}
								noEqs = assignments.notEqHs(corrAtoms[corr].atom);
								if (noEqs === 1) {
									corrString += atomLabel;
									break;
								} else {
									corrString += Str.atomIndexToString(atomLabel, corrAtoms[corr].atom, corrAtoms[corr].indexes[indx], true);
								}
							}
						}
						if (corrString !== undefined) {
							strm.write(corrString, "\t");
						} else {
							strm.write("\t");
						}
					}

					//protons
					if (atom.elementSymbol !== "H") {
						noEqHs = assignments.notEqHs(ai);
						for (hIndex = 0; hIndex < noEqHs.length; hIndex++) {
							h = noEqHs[hIndex];
							protonLabel = "H";
							if (noEqHs === 1) {
								if (atom.nH > 1) {
									protonLabel += atom.nH;
								}
							} else {
								protonLabel += Str.hIndexToLetter(h);
							}
							strm.write("\n", protonLabel, "\t");
							shift =  assignments.chemShift(ai, h);
							if (shift !== undefined) {
								shift = shift.shift.toFixed(decimals);
								strm.write(shift, "\t");
							} else {
								strm.write("\t");
							}
							for (c = 0; c < corrArray.length; c++) {
								corrAtoms = assignments.correlatedAtoms(ai, h, corrArray[c]);
								corrString = "";
								for (corr = 0; corr < corrAtoms.length; corr++) {
									if (corr > 0) {
										corrString += ", ";
									}
									atomLabel = mol.atom(corrAtoms[corr].atom).number;
									for (indx = 0; indx < corrAtoms[corr].indexes.length; indx++) {
										if (indx > 0) {
											corrString  += ", ";
										}
										noEqs = assignments.notEqHs(corrAtoms[corr].atom);
										if (noEqs === 1) {
											corrString += atomLabel;
											break;
										} else {
											corrString += Str.atomIndexToString(atomLabel, corrAtoms[corr].atom, corrAtoms[corr].indexes[indx], true);
										}
									}
								}
								if (corrString !== undefined) {
									strm.write(corrString, "\t");
								} else {
									strm.write("\t");
								}
							}
						}
					}
					strm.write("\n");
				}
			}
		}
		file.close();
		return 0;
	}

	return 1;
};

/** Add to the Env.Converters environment engine
 */
Env.Converters.push(new AssignmentsConverter());

//test
function assignmentsConverterTest() {
	"use strict";
	var retVal = -1,
		assignsConv = new AssignmentsConverter(),
		pageItems = Application.mainWindow.activeDocument.selection();

	if (assignsConv.wantsExport(pageItems)) {
		retVal = assignsConv.exportItems(pageItems, "C:/Users/Usuario/Desktop/Assignments.txt");
	}
	return retVal;
}
